#include "app_buffer.h"
#include <stdlib.h>
#include "string.h"

Buffer *app_buffer_init(int size)
{
    Buffer *buffer;
    buffer = malloc(sizeof(Buffer));
    if (buffer == NULL)
    {
        log_error("Buffer malloc failed");
        return NULL;
    }
    buffer->len = 0;
    buffer->offset = 0;
    buffer->total_size = size;
    buffer->ptr = malloc(size);
    if (buffer->ptr == NULL)
    {
        log_error("buffer malloc failed");
        free(buffer);
        return NULL;
    }
    return buffer;
}

int app_buffer_write(Buffer *buff, char *data, int len)
{
    if (buff == NULL | data == NULL | len <= 0)
    {
        log_error("app_buffer_write invalid parameters");
        return -1;
    }
    if (buff->len + len > buff->total_size)
    {
        log_error("app_buffer_write buffer overflow");
        return -1;
    }
    int write_start = 0;
    if (buff->offset + buff->len < buff->total_size)
    {
        write_start = buff->offset + buff->len;
    }
    else
    {
        write_start = buff->offset + buff->len - buff->total_size;
    }
    if (write_start + len < buff->total_size)
    {
        // 写一次
        memcpy(buff->ptr + write_start, data, len);
    }
    else
    {
        // 写两次
        int len1 = buff->total_size - write_start;
        memcpy(buff->ptr + write_start, data, len1);
        memcpy(buff->ptr, data + len1, len - len1);
    }
    buff->len += len;
    log_debug("app_buffer_write len=%d, offset=%d, len=%d, data=%s", buff->len, buff->offset, len, buff->ptr);
    return 0;
}

int app_buffer_read(Buffer *buff, char *data, int len)
{
    if (buff == NULL | data == NULL | len <= 0 | len > buff->len)
    {
        log_error("app_buffer_read invalid parameters");
        return -1;
    }
    if (buff->offset + len < buff->total_size)
    {
        // 读一次
        memcpy(data, buff->ptr + buff->offset, len);
        buff->offset += len;
    }
    else
    {
        // 读两次
        int len1 = buff->total_size - buff->offset;
        memcpy(data, buff->ptr + buff->offset, len1);
        memcpy(data + len1, buff->ptr, len - len1);
        buff->offset = len - len1;
    }
    buff->len -= len;
    log_debug("app_buffer_read len=%d, offset=%d, len=%d, data=%s", buff->len, buff->offset, len, buff->ptr);
    return 0;
}

int app_buffer_free(Buffer *buff)
{
    if (buff == NULL)
    {
        return 0;
    }
    free(buff->ptr);
    free(buff);
    return 0;
}